package com.kjlink.internal.workreport.jira.service;

import cn.xuqiudong.common.base.vo.BooleanWithMsg;
import com.kjlink.internal.workreport.base.enums.JiraCheckResult;
import com.kjlink.internal.workreport.config.db.JdbcTemplateConfig;
import com.kjlink.internal.workreport.jira.helper.SqlServerJiraSqlHelper;
import com.kjlink.internal.workreport.jira.model.Jira;
import com.kjlink.internal.workreport.jira.vo.JiraSynchronousResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 描述:
 * jira 同步service
 *
 * @author Vic.xu
 * @since 2025-01-11 11:09
 */
@Service
public class JiraSynchronousService {

    private static final Logger LOGGER = LoggerFactory.getLogger(JiraSynchronousService.class);

    @Resource
    private JiraService jiraService;

    /**
     * 工银 jira 数据源
     */
    @Resource(name = JdbcTemplateConfig.JIRA_JDBC_TEMPLATE)
    private JdbcTemplate jiraJdbcTemplate;

    /**
     * 非工银 jira 数据源
     */
    @Resource(name = JdbcTemplateConfig.JIRA2_JDBC_TEMPLATE)
    private JdbcTemplate jira2JdbcTemplate;

    /**
     * 获得工银的某天的jira
     */
    public List<Jira> getGongyinJiraList(LocalDate date) {
        Pair<String, Object[]> pair = SqlServerJiraSqlHelper.buildQueryJiraSqlByCreateDate(date);
        return getJiraList(jiraJdbcTemplate, pair);
    }

    /**
     * 获得非工银的某天的jira
     */
    public List<Jira> getNotGongyinJiraList(LocalDate date) {
        Pair<String, Object[]> pair = SqlServerJiraSqlHelper.buildQueryJiraSqlByCreateDate(date);
        return getJiraList(jira2JdbcTemplate, pair);
    }

    /**
     * 获取工银的某段时间的jira
     */
    public List<Jira> getGongyinJiraList(LocalDate startDate, LocalDate endDate) {
        Pair<String, Object[]> pair = SqlServerJiraSqlHelper.buildQueryJiraSqlBetweenCreateDate(startDate, endDate);
        return getJiraList(jiraJdbcTemplate, pair);
    }

    /**
     * 获取非工银的某段时间的jira
     */
    public List<Jira> getNotGongyinJiraList(LocalDate startDate, LocalDate endDate) {
        Pair<String, Object[]> pair = SqlServerJiraSqlHelper.buildQueryJiraSqlBetweenCreateDate(startDate, endDate);
        return getJiraList(jira2JdbcTemplate, pair);
    }

    /**
     * 根据jira 号列表查询 工银的jira 列表
     */
    public List<Jira> getGongyinJiraList(List<String> codes) {
        return getJiraByCodes(jiraJdbcTemplate, codes);
    }

    /**
     * 根据jira 号列表查询 非工银的jira 列表
     * @param codes
     * @return
     */
    public List<Jira> getNotGongyinJiraList(List<String> codes) {
        return getJiraByCodes(jira2JdbcTemplate, codes);
    }

    /**
     * 根据jira 号列表查询jira
     * @param jdbcTemplate
     * @param codes
     * @return
     */
    public List<Jira> getJiraByCodes(JdbcTemplate jdbcTemplate, List<String> codes){
        if (CollectionUtils.isEmpty(codes)) {
            return new ArrayList<>();
        }
        String sql = SqlServerJiraSqlHelper.getQueryJiraSql() + " AND a.pkey IN (:codes) ";

        // 每批次的最大长度
        int batchSize = 500;
        List<Jira> result = new ArrayList<>();
        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
        // 分批处理
        for (int i = 0; i < codes.size(); i += batchSize) {
            List<String> batchCodes = codes.subList(i, Math.min(i + batchSize, codes.size()));
            MapSqlParameterSource parameters = new MapSqlParameterSource();
            parameters.addValue("codes", batchCodes);
            result.addAll(namedParameterJdbcTemplate.query(sql, parameters, new BeanPropertyRowMapper<>(Jira.class)));
        }

        return result;

    }



    /**
     * 根据数据库 和 sql和条件查询 jira
     *
     * @param jdbcTemplate 对应数据库
     * @param pair         sql和条件
     * @return jira list
     */
    public List<Jira> getJiraList(JdbcTemplate jdbcTemplate, Pair<String, Object[]> pair) {
        Object[] args = pair.getRight();
        String sql = pair.getLeft();
        return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Jira.class), args);
    }

    /**
     * 根据从异构数据库查询的结构同步到本地 false: 已存在，无需导入; true:  状态变化 | 发生错误 | 新导入
     * @return false: 只有 "已存在，无需导入" 的情况 才算 没有changed, 其他情况都需要记录
     */
    public BooleanWithMsg synchronousJira(Jira jira, JiraSynchronousResult result) {
        if (result == null) {
            result = new JiraSynchronousResult();
        }
        boolean changed = true;
        StringBuilder sb = new StringBuilder();
        String code = jira.getCode();
        sb.append("【").append(code).append("】");
        try {
            Jira jiraByCode = jiraService.getJiraByCode(code);
            if (jiraByCode != null) {
                // 判断远程jira是否变化
                BooleanWithMsg updated = updateJiraOtherFieldFromDb(jiraByCode, jira);
                // 判断状态是否改变
                if (!updated.isSuccess()) {
                    sb.append("已存在，无需导入");
                    result.addNoChangeCount();
                    changed = false;
                } else {
                    sb.append(updated.getMessage());
                    result.addStatusUpdatedCount();
                }

            } else {
                jira.setCheckResult(JiraCheckResult.success);
                jira.setSettleYear(jiraService.getSettleYear());
                jiraService.save(jira);
                sb.append("导入成功");
                result.addNewImportCount();
            }
        } catch (Exception e) {
            //导入失败 也算changed  需记录
            LOGGER.error("导入jira失败", e);
            sb.append("导入失败:" + e.getMessage());
            result.addFailedCount();
        }
        // 只有 已存在，无需导入 的情况 才算 没有changed
        return BooleanWithMsg.success(sb.toString()).setSuccess(changed);
    }


    /**
     *  jira 是否有变化，以及哪些变化，并更新本地jira
     *  变化了  返回 true 和变化信息
     */
    public BooleanWithMsg updateJiraOtherFieldFromDb(Jira localJira, Jira dbJira){
        if (localJira == null || dbJira == null) {
            return BooleanWithMsg.fail("");
        }
        // 更新本地jira
        Jira user2update = new Jira();
        user2update.setId(localJira.getId());
        boolean changed = false;
        StringBuilder msg = new StringBuilder();
        // 更新状态
        if (StringUtils.isNotBlank(dbJira.getStatus())) {
            if (!StringUtils.equals(localJira.getStatus(), dbJira.getStatus())) {
                user2update.setStatus(dbJira.getStatus());
                changed = true;
                msg.append("状态从[").append(localJira.getStatus()).append("]更新为[")
                        .append(dbJira.getStatus()).append("];");
            }
        }
        //  更新类型
        if (StringUtils.isNotBlank(dbJira.getType())) {
            if (!StringUtils.equals(localJira.getType(), dbJira.getType())) {
                user2update.setType(dbJira.getType());
                changed = true;
                msg.append("类型从[").append(localJira.getType()).append("]更新为[")
                        .append(dbJira.getType()).append("];");
            }
        }
        //更新 父jira
        if (StringUtils.isNotBlank(dbJira.getPcode())) {
            if (!StringUtils.equals(localJira.getPcode(), dbJira.getPcode())) {
                user2update.setPcode(dbJira.getPcode());
                changed = true;
                msg.append("父jira从[").append(localJira.getPcode()).append("]更新为[")
                        .append(dbJira.getPcode()).append("];");
            }
        }
        // 更新经办人
        if (StringUtils.isNotBlank(dbJira.getAssignee())) {
            if (!StringUtils.equals(localJira.getAssignee(), dbJira.getAssignee())) {
                user2update.setAssignee(dbJira.getAssignee());
                changed = true;
                msg.append("经办人从[").append(localJira.getAssignee()).append("]更新为[")
                        .append(dbJira.getAssignee()).append("];");
            }
        }

        //更新内容
        if (StringUtils.isNotBlank(dbJira.getContent())) {
            if (!StringUtils.equals(localJira.getContent(), dbJira.getContent())) {
                user2update.setContent(dbJira.getContent());
                changed = true;
                msg.append("内容从[").append(localJira.getContent()).append("]更新为[")
                        .append(dbJira.getContent()).append("];");
            }
        }
        if (!changed) {
            return BooleanWithMsg.fail("");
        } else {
            LOGGER.info("jira [{}] has changed !", localJira.getCode());
            //更新本地jira，并返回变化说明
            jiraService.update(user2update);
            return BooleanWithMsg.success(msg.toString());
        }
    }
}
